{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# 各类排序算法性能对比"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 排序算法复杂度整理\n",
    "\n",
    "| 排序算法 | English | 时 间 复 杂 度 | 空 间 复 杂 度 |\n",
    "| :---: | :---: | :---: | :---: |\n",
    "| 冒泡排序 | BubbleSort | $O(n^2)$        | $O(1)$          |\n",
    "| 选择排序 | SelectSort | $O(n^2)$        | $O(1)$          |\n",
    "| 插入排序 | InsertSort | $O(n^2)$        | $O(1)$          |\n",
    "| 希尔排序 | ShellSort  | $O(n^{1.5})$       | $O(1)$          |\n",
    "| 快速排序 | QuickSort  | $O(Nlog_2N)$ | $O(log_2N)$ |\n",
    "| 归并排序 | MergeSort  | $O(Nlog_2N)$ | $O(N)$          |\n",
    "| 堆排序   | HeapSort   | $O(Nlog_2N)$ | $O(1)$          |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import copy, time\n",
    "from sort import *\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 待测试排序算法\n",
    "# Python: SortFunc\n",
    "# C:      SortFuncC"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 基本排序测试 (Python)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python Sort Test\n",
      "[Function SortStd] Time Duration:0.001000s\n",
      "[Class   BubbleSort]: Time Duration: 0.593043s, Check: True SwapCount =     239341, SearchCount =     999000\n",
      "[Class   SelectSort]: Time Duration: 0.226017s, Check: True SwapCount =        997, SearchCount =     499500\n",
      "[Class   InsertSort]: Time Duration: 0.130009s, Check: True SwapCount =          0, SearchCount =     240340\n",
      "[Class    QuickSort]: Time Duration: 0.008000s, Check: True SwapCount =       3108, SearchCount =      10761\n",
      "[Class   QuickSort2]: Time Duration: 0.007000s, Check: True SwapCount =       1892, SearchCount =      11167\n",
      "[Class    ShellSort]: Time Duration: 0.015001s, Check: True SwapCount =          0, SearchCount =      16639\n",
      "[Class    MergeSort]: Time Duration: 0.007000s, Check: True SwapCount =          0, SearchCount =       9735\n",
      "[Class     HeapSort]: Time Duration: 0.013002s, Check: True SwapCount =       9115, SearchCount =      16857\n"
     ]
    }
   ],
   "source": [
    "print(\"Python Sort Test\")\n",
    "RandList = GenRandNum(1000)\n",
    "StdList = SortStd(copy.copy(RandList))\n",
    "for cSort in SortFunc:\n",
    "    SortTest(cSort, copy.copy(RandList), StdList)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### MonteCarlo测试"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***创建测试函数 (Both For C/Python Sort)***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def SortTestRep(SortList, SortTestFunc, NumLen = 100, Times = 10):\n",
    "    # init\n",
    "    keys = ['Swap','Search','Time']\n",
    "    keysAvg = ['AvgSwap','AvgSearch','AvgTime']\n",
    "    TestResult = {}\n",
    "    for Sort in SortList:\n",
    "        TestResult[Sort.__name__] = dict.fromkeys(keys+keysAvg)\n",
    "        for key, keyAvg in zip(keys, keysAvg):\n",
    "            TestResult[Sort.__name__][key] = []\n",
    "            TestResult[Sort.__name__][keyAvg] = 0\n",
    "    \n",
    "    # run tests\n",
    "    for i in range(Times):\n",
    "        RandomNumbers = GenRandNum(NumLen)\n",
    "        for Sort in SortList:\n",
    "            result = SortTestFunc(Sort, RandomNumbers, PrintFlag=False)\n",
    "            for key in keys:\n",
    "                TestResult[Sort.__name__][key].append(result[key])\n",
    "    \n",
    "    # analyse\n",
    "    for Sort in SortList:\n",
    "        for key, keyAvg in zip(keys, keysAvg):\n",
    "            if(TestResult[Sort.__name__][key][0]):\n",
    "                TestResult[Sort.__name__][keyAvg] = sum(TestResult[Sort.__name__][key])/Times\n",
    "    \n",
    "    return TestResult"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***测试算法***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# run test (cost a period of time, suggest run once)\n",
    "TestResult = SortTestRep(SortFunc, SortTest, NumLen = 1000, Times = 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           AvgSearch AvgSwap     AvgTime\n",
      "BubbleSort    999000  250841    0.586647\n",
      "SelectSort    499500   991.8    0.223714\n",
      "InsertSort    251840       0    0.138813\n",
      "QuickSort      10999  3051.2  0.00779655\n",
      "QuickSort2   11388.6  1872.4   0.0073014\n",
      "ShellSort    15560.2       0   0.0143015\n",
      "MergeSort     9710.6       0  0.00709918\n",
      "HeapSort     16852.1  9081.4    0.013902\n"
     ]
    }
   ],
   "source": [
    "# using pandas to analyse\n",
    "dfTest = pd.DataFrame(TestResult).T\n",
    "keysToAnalyse = ['AvgSearch','AvgSwap','AvgTime']\n",
    "dfTestToPrint = dfTest.loc[:,keysToAnalyse]\n",
    "print(dfTestToPrint)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***作图分析***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def PlotResult(dfTest, keysToAnalyse):\n",
    "    # parameters\n",
    "    NumAnalyse = len(keysToAnalyse)\n",
    "    fig = plt.figure()\n",
    "    fig.set_figheight(5)\n",
    "    fig.set_figwidth(15)\n",
    "    bar_width = 0.7\n",
    "    opacity = 0.4\n",
    "\n",
    "    # bar plots\n",
    "    for i,key in zip(range(NumAnalyse),keysToAnalyse):\n",
    "        data = dfTest.loc[:,key]\n",
    "        ax = fig.add_subplot(1,NumAnalyse,i+1)\n",
    "        index = np.arange(len(data))\n",
    "        rects = plt.bar(index, data, bar_width,\n",
    "                         alpha=opacity,\n",
    "                         color='b')\n",
    "        plt.ylabel(key)\n",
    "        plt.xticks(index, dfTest.index, rotation=90)\n",
    "        plt.tight_layout()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "PlotResult(dfTest, keysToAnalyse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 优化排序测试 (C Language)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C Sort Test\n",
      "[Function SortStd] Time Duration:0.211018s\n",
      "[Func    SortBubble]: Time Duration: 22.136637s, Check: True\n",
      "[Func    SortSelect]: Time Duration: 2.887213s, Check: True\n",
      "[Func    SortInsert]: Time Duration: 1.622130s, Check: True\n",
      "[Func     SortShell]: Time Duration: 0.033998s, Check: True\n",
      "[Func     SortQuick]: Time Duration: 0.032001s, Check: True\n",
      "[Func    SortQuick2]: Time Duration: 0.032011s, Check: True\n",
      "[Func     SortMerge]: Time Duration: 0.042012s, Check: True\n",
      "[Func      SortHeap]: Time Duration: 0.036003s, Check: True\n"
     ]
    }
   ],
   "source": [
    "print(\"C Sort Test\")\n",
    "RandList = GenRandNum(100000)\n",
    "StdList = SortStd(copy.copy(RandList))\n",
    "for fSort in SortFuncC:\n",
    "    SortTestC(fSort, copy.copy(RandList), StdList)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### MonteCarlo测试  (C Language)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***测试算法***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# run test (cost a period of time, suggest run once)\n",
    "TestResultC = SortTestRep(SortFuncC, SortTestC, NumLen = 10000, Times = 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               AvgTime\n",
      "SortBubble    0.163914\n",
      "SortSelect   0.0297012\n",
      "SortInsert   0.0186012\n",
      "SortShell   0.00350044\n",
      "SortQuick   0.00330195\n",
      "SortQuick2  0.00330017\n",
      "SortMerge   0.00440016\n",
      "SortHeap    0.00310249\n"
     ]
    }
   ],
   "source": [
    "# using pandas to analyse\n",
    "dfTestC = pd.DataFrame(TestResultC).T\n",
    "keysToAnalyse = ['AvgTime']\n",
    "dfTestToPrintC = dfTestC.loc[:,keysToAnalyse]\n",
    "print(dfTestToPrintC)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***作图分析***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "PlotResult(dfTestC, keysToAnalyse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***Compare of Shell, Quick, Quick+Insert, Merge, Heap***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# run test (cost a period of time, suggest run once)\n",
    "SortFuncC_Ex = [\n",
    "    sort_lib.SortShell,\n",
    "    sort_lib.SortQuick,\n",
    "    sort_lib.SortQuick2,\n",
    "    sort_lib.SortMerge,\n",
    "    sort_lib.SortHeap\n",
    "]\n",
    "TestResultC_Ex = SortTestRep(SortFuncC_Ex, SortTestC, NumLen = 1000000, Times = 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "             AvgTime\n",
      "SortShell   0.449027\n",
      "SortQuick   0.373444\n",
      "SortQuick2  0.361405\n",
      "SortMerge   0.510302\n",
      "SortHeap    0.477107\n"
     ]
    }
   ],
   "source": [
    "dfTestC_Ex = pd.DataFrame(TestResultC_Ex).T\n",
    "keysToAnalyse = ['AvgTime']\n",
    "dfTestToPrintC_Ex = dfTestC_Ex.loc[:,keysToAnalyse]\n",
    "print(dfTestToPrintC_Ex)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***作图分析***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "PlotResult(dfTestC_Ex, keysToAnalyse)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
